/*
 *   Copyright 2012-present OSBI Ltd
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */

// Packages
import React, { Component, Fragment } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import {
  Alignment,
  Navbar,
  NavbarDivider,
  NavbarGroup,
  Popover,
  Position
} from '@blueprintjs/core';

// Actions
import { actionCreators } from '../../../actions';

// Toolbar Item
import WTItem from './WTItem';
import WTSaveMenu from './WTSaveMenu';
import WTExportMenu from './WTExportMenu';
import WTChartMenu from './WTChartMenu';

// Icons
import { chartItems } from '../../../images/chart-icons';

// Dialogs
import { CubesDialog, ShowMdxDialog } from '../../Dialogs';

// Alerts
import RefreshCubes from '../../Alerts/RefreshCubes';

// Utils
import { Saiku } from '../../../utils';

// Styles
import './WorkspaceToolbar.css';

class WorkspaceToolbar extends Component {
  state = {
    isOpenCubesDialog: false,
    isOpenRefreshCubesAlert: false,
    isShowMdxDialog: false
  };

  handleCubesDialog = () => {
    this.setState(prevState => ({
      isOpenCubesDialog: !prevState.isOpenCubesDialog
    }));
  };

  handleRefreshCubesAlert = () => {
    this.setState(prevState => ({
      isOpenRefreshCubesAlert: !prevState.isOpenRefreshCubesAlert
    }));
  };

  handleOpenQueryDialog = () => {
    this.props.openQuery();
  };

  handleResetQueryAlert = () => {
    this.props.resetQuery();
  };

  handleQueryDesignerDialog = () => {
    this.props.queryDesigner();
  };

  handleHideParents = async () => {
    const { query, setQueryProperty, olapQueryRun } = this.props;
    const propertyFormatter = Saiku.getProperty(
      'saiku.olap.result.formatter',
      query
    );
    const formatter = propertyFormatter === 'flattened' ? 'flat' : 'flattened';

    await setQueryProperty({ 'saiku.olap.result.formatter': formatter });
    olapQueryRun();
  };

  handleNonEmpty = async () => {
    const { query, setQueryProperty, olapQueryRun } = this.props;
    const isPropertyNonEmpty = !Saiku.getProperty(
      'saiku.olap.query.nonempty',
      query
    );

    await setQueryProperty({
      'saiku.olap.query.nonempty': isPropertyNonEmpty
    });
    olapQueryRun();
  };

  handleShowMdxDialog = () => {
    this.setState(prevState => ({
      isShowMdxDialog: !prevState.isShowMdxDialog
    }));
  };

  handleSwitchRender(renderMode, chartType = null) {
    const { setQueryProperty, switchRender } = this.props;

    setQueryProperty({ 'saiku.ui.render.mode': renderMode });
    setQueryProperty({ 'saiku.ui.render.type': chartType });
    switchRender(renderMode, chartType);
  }

  handleRequestFullscreen = () => {
    this.props.requestFullscreen();
  };

  render() {
    const { hasResultset, query, queryResultset, saveQuery } = this.props;
    const hasPropertyFormatter = Saiku.getProperty(
      'saiku.olap.result.formatter',
      query
    );
    const isPropertyNonEmpty = Saiku.getProperty(
      'saiku.olap.query.nonempty',
      query
    );
    const { hasRun } = queryResultset;
    const { workspace } = this.props.workspace;
    const { renderMode, chartType } = workspace;
    const {
      isOpenCubesDialog,
      isOpenRefreshCubesAlert,
      isShowMdxDialog
    } = this.state;

    return (
      <Fragment>
        <Navbar className="sku-workspace-toolbar">
          <NavbarGroup align={Alignment.LEFT}>
            <WTItem
              icon="cube"
              content="Cubes"
              action={this.handleCubesDialog}
            />
            <WTItem
              icon="refresh"
              content="Refresh Cubes (Clear Cache)"
              action={this.handleRefreshCubesAlert}
            />
            <NavbarDivider />
            <WTItem
              icon="folder-close"
              content="Open Query"
              action={this.handleOpenQueryDialog}
            />
            <Popover
              content={<WTSaveMenu saveQueryDialog={saveQuery} />}
              position={Position.BOTTOM}
              autoFocus={false}
              enforceFocus={false}
              disabled={!hasRun}
            >
              <WTItem
                icon="floppy-disk"
                content="Save Query"
                disabled={!hasRun}
              />
            </Popover>
            <NavbarDivider />
            <WTItem
              icon="document"
              content="Reset Query"
              disabled={!hasRun}
              action={this.handleResetQueryAlert}
            />
            <WTItem
              icon="edit"
              content="Query Designer"
              disabled={!query.cube && !hasRun}
              action={this.handleQueryDesignerDialog}
            />
            <NavbarDivider />
            <WTItem
              icon="th-derived"
              content="Hide Parents"
              active={hasPropertyFormatter === 'flattened'}
              disabled={!hasPropertyFormatter || !hasRun}
              action={this.handleHideParents}
            />
            <WTItem
              icon="th-disconnect"
              content="Non-empty"
              active={isPropertyNonEmpty}
              disabled={!hasRun}
              action={this.handleNonEmpty}
            />
            <NavbarDivider />
            <WTItem
              icon="code"
              content="Show MDX"
              disabled={!hasRun}
              action={this.handleShowMdxDialog}
            />
            <NavbarDivider />
            <Popover
              content={<WTExportMenu />}
              position={Position.BOTTOM}
              autoFocus={false}
              enforceFocus={false}
              disabled={!hasRun}
            >
              <WTItem icon="export" content="Export" disabled={!hasRun} />
            </Popover>
            <NavbarDivider />
            <WTItem
              icon="th"
              content="Table Mode"
              active={renderMode === 'table'}
              disabled={!hasRun}
              action={this.handleSwitchRender.bind(this, 'table')}
            />
            <Popover
              content={
                <WTChartMenu
                  hasResultset={hasResultset}
                  chartItems={chartItems}
                  type={chartType}
                  setChartType={this.handleSwitchRender.bind(this)}
                />
              }
              position={Position.BOTTOM}
              autoFocus={false}
              enforceFocus={false}
              disabled={!hasRun}
            >
              <WTItem
                icon="timeline-bar-chart"
                content="Chart Mode"
                active={renderMode === 'chart'}
                disabled={!hasRun}
              />
            </Popover>
            <NavbarDivider />
            <WTItem
              icon="fullscreen"
              content="Fullscreen"
              disabled={!hasRun}
              action={this.handleRequestFullscreen}
            />
          </NavbarGroup>
        </Navbar>

        {isOpenCubesDialog && <CubesDialog onClose={this.handleCubesDialog} />}

        {isOpenRefreshCubesAlert && (
          <RefreshCubes onCancel={this.handleRefreshCubesAlert} />
        )}

        {isShowMdxDialog && (
          <ShowMdxDialog onClose={this.handleShowMdxDialog} />
        )}
      </Fragment>
    );
  }
}

WorkspaceToolbar.propTypes = {
  query: PropTypes.object.isRequired,
  queryResultset: PropTypes.object.isRequired,
  workspace: PropTypes.object.isRequired,
  hasResultset: PropTypes.bool.isRequired,
  openQuery: PropTypes.func.isRequired,
  saveQuery: PropTypes.func.isRequired,
  resetQuery: PropTypes.func.isRequired,
  queryDesigner: PropTypes.func.isRequired,
  requestFullscreen: PropTypes.func.isRequired,
  setQueryProperty: PropTypes.func.isRequired,
  switchRender: PropTypes.func.isRequired,
  olapQueryRun: PropTypes.func.isRequired
};

const mapDispatchToProps = dispatch => ({
  setQueryProperty: data => dispatch(actionCreators.setQueryProperty(data)),
  switchRender: (renderMode, chartType) =>
    dispatch(actionCreators.switchRender(renderMode, chartType)),
  olapQueryRun: query => dispatch(actionCreators.olapQueryRun(query))
});

export default connect(
  null,
  mapDispatchToProps
)(WorkspaceToolbar);
